﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace XgPushTest
{
    /// <summary>
    /// Handler1 的摘要说明,   http://localhost:50694/Handler1.ashx
    /// </summary>
    public class Handler1 : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            string backTxt = string.Empty;
            int code = 0;//返回的执行状态码
            string jsonTxt = string.Empty;//参数data的base64字符串解码后的字符串
            string method = context.Request["method"];//请求方法
            string pushType = context.Request["pushType"];//消息类型，1=通知，2=透传消息
            string appType = context.Request["appType"];//app的版本，是家长版1，还是教师版2    
            string data = context.Request["data"];//json格式数据，经base64编码过

            #region 数据验证

            if (string.IsNullOrEmpty(method) || string.IsNullOrWhiteSpace(method))
            {
                code = 1;
                backTxt = "参数method不能为空";
                string saveFolder = "Log";
                LogManager.AddLog(backTxt, saveFolder);
                ResponseWrite(code, backTxt, ref context);
                return;
            }
            if (string.IsNullOrEmpty(pushType) || string.IsNullOrWhiteSpace(pushType))
            {
                code = 1;
                backTxt = "参数pushType不能为空";
                string saveFolder = "Log";
                LogManager.AddLog(backTxt, saveFolder);
                ResponseWrite(code, backTxt, ref context);
                return;
            }
            string[] typeArray = { "1", "2" };
            bool isCun = typeArray.Contains(pushType);
            if (isCun == false)
            {
                code = 1;
                backTxt = "参数pushType值无效";
                string saveFolder = "Log";
                LogManager.AddLog(backTxt, saveFolder);
                ResponseWrite(code, backTxt, ref context);
                return;
            }
            if (string.IsNullOrEmpty(appType) || string.IsNullOrWhiteSpace(appType))
            {
                code = 1;
                backTxt = "参数appType不能为空";
                string saveFolder = "Log";
                LogManager.AddLog(backTxt, saveFolder);
                ResponseWrite(code, backTxt, ref context);
                return;
            }
            if (string.IsNullOrEmpty(data) || string.IsNullOrWhiteSpace(data))
            {
                code = 1;
                backTxt = "参数data不能为空";
                string saveFolder = "Log";
                LogManager.AddLog(backTxt, saveFolder);
                ResponseWrite(code, backTxt, ref context);
                return;
            }
            #endregion
            try
            {
                #region 数据格式验证

                DbDao dao = new DbDao();
                //获取android推送配置
                AppPushSettingInfo pushinfo_android = dao.GetAppSetting(appType);
                //获取对应版本ios推送配置
                AppPushSettingInfo pushinfo_ios = dao.GetAppSetting(appType + "" + appType);
                if (pushinfo_android == null)
                {
                    code = 1;
                    backTxt = "不是有效的参数appType值";
                    string saveFolder = "Log";
                    LogManager.AddLog(backTxt, saveFolder);
                    ResponseWrite(code, backTxt, ref context);
                    return;
                }
                List<AppPushSettingInfo> push_info_list = new List<AppPushSettingInfo>();
                push_info_list.Add(pushinfo_android);
                push_info_list.Add(pushinfo_ios);

                MsgInfo msginfo = null;
                try
                {
                    byte[] outputb = Convert.FromBase64String(data);
                    jsonTxt = System.Text.Encoding.UTF8.GetString(outputb);
                }
                catch (Exception)
                {
                    code = 1;
                    backTxt = "参数data不是有效的base64字符串";
                    string saveFolder = "Log";
                    LogManager.AddLog(backTxt + "，参数data=" + data, saveFolder);
                    ResponseWrite(code, backTxt, ref context);
                    return;
                }
                try
                {
                    msginfo = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgInfo>(jsonTxt);
                }
                catch (Exception)
                {
                    code = 1;
                    backTxt = "参数data的json格式不正确";
                    string saveFolder = "Log";
                    LogManager.AddLog(backTxt + "，参数data=" + data, saveFolder);
                    ResponseWrite(code, backTxt, ref context);
                    return;
                }
                //解码数据
                string orgStr_Title = string.Empty;
                string orgStr_Msg = string.Empty;
                try
                {
                    byte[] outputb_Title = Convert.FromBase64String(msginfo.title);
                    orgStr_Title = System.Text.Encoding.UTF8.GetString(outputb_Title);//推送的标题
                    byte[] outputb_Msg = Convert.FromBase64String(msginfo.msg);
                    orgStr_Msg = System.Text.Encoding.UTF8.GetString(outputb_Msg);//推送的消息  
                }
                catch (Exception)
                {
                    code = 1;
                    backTxt = "标题或消息不是有效的Base64字符串";
                    string saveFolder = "Log";
                    LogManager.AddLog(backTxt, saveFolder);
                    ResponseWrite(code, backTxt, ref context);
                    return;
                }
                if (string.IsNullOrEmpty(orgStr_Title) || string.IsNullOrWhiteSpace(orgStr_Title))
                {
                    code = 1;
                    backTxt = "推送标题不能为空";
                    string saveFolder = "Log";
                    LogManager.AddLog(backTxt, saveFolder);
                    ResponseWrite(code, backTxt, ref context);
                    return;
                }
                if (string.IsNullOrEmpty(orgStr_Msg) || string.IsNullOrWhiteSpace(orgStr_Msg))
                {
                    code = 1;
                    backTxt = "推送消息不能为空";
                    string saveFolder = "Log";
                    LogManager.AddLog(backTxt, saveFolder);
                    ResponseWrite(code, backTxt, ref context);
                    return;
                }
                #endregion

                if (method.Equals("PushAll"))
                {
                    #region 推送所有设备

                    //data格式：{"title":"宝贝家园","msg":""}                     
                    PushBackMsg backMsg = PushAll(orgStr_Title, orgStr_Msg, pushType, push_info_list);
                    code = backMsg.code;
                    backTxt = backMsg.msg;

                    #endregion
                }
                else if (method.Equals("TagsDevice"))
                {
                    #region 标签推送

                    //data格式：{"title":"宝贝家园","msg":"","tag":"jiazhang"}                                                               
                    if (string.IsNullOrEmpty(msginfo.tag) || string.IsNullOrWhiteSpace(msginfo.tag))
                    {
                        code = 1;
                        backTxt = "标签tag不能为空";
                        string saveFolder = "Log";
                        LogManager.AddLog(backTxt, saveFolder);
                        ResponseWrite(code, backTxt, ref context);
                        return;
                    }
                    PushBackMsg backMsg = TagsDevice(orgStr_Title, orgStr_Msg, msginfo.tag, pushType, push_info_list);
                    code = backMsg.code;
                    backTxt = backMsg.msg;

                    #endregion
                }
                else if (method.Equals("SingleAccount"))//推送单个账号
                {
                    #region 推送单个账号

                    //data格式：{"title":"宝贝家园","msg":"","account":"112"}                       
                    if (string.IsNullOrEmpty(msginfo.account) || string.IsNullOrWhiteSpace(msginfo.account))
                    {
                        code = 1;
                        backTxt = "账号不能为空";
                        string saveFolder = "Log";
                        LogManager.AddLog(backTxt, saveFolder);
                        ResponseWrite(code, backTxt, ref context);
                        return;
                    }
                    string account = msginfo.account.Trim();
                    PushBackMsg backMsg = SingleAccount(orgStr_Title, orgStr_Msg, account, pushType, push_info_list);
                    code = backMsg.code;
                    backTxt = backMsg.msg;

                    #endregion
                }
                else
                {
                    code = 1;
                    backTxt = "调用方法不存在";
                    string saveFolder = "Log";
                    LogManager.AddLog(backTxt + ",调用方法名=" + method, saveFolder);
                }
            }
            catch (Exception ex)
            {
                code = 1;
                backTxt = "处理异常";
                string saveFolder = "Log";
                LogManager.AddLog(ex.Message, saveFolder);
            }
            ResponseWrite(code, backTxt, ref context);
        }

        /// <summary>
        /// 返回调用者响应消息
        /// </summary>
        /// <param name="code">状态码，0=成功，1=失败</param>
        /// <param name="backTxt">消息</param>
        /// <param name="context">当前HttpContext上下文</param>
        public void ResponseWrite(int code, string backTxt, ref HttpContext context)
        {
            //返回消息格式 0=成功，1=失败
            string backJson = "{\"code\":" + code + ",\"msg\":\"" + backTxt + "\"}";
            context.Response.Write(backJson);
        }

        //推送到所有设备，测试专用
        public PushBackMsg PushAll(string title, string msg, string pushType, List<AppPushSettingInfo> pushinfolist)
        {
            string method = "POST";
            string url = "openapi.xg.qq.com/v2/push/all_device";
            AppPushSettingInfo android_info = pushinfolist[0];//安卓版配置信息实体【下标为0】
            string accessId = "access_id=" + android_info.Access_id;
            string secret_key = android_info.Secret_key;
            long utck = (DateTime.UtcNow.Ticks - Convert.ToDateTime("1970-01-01").Ticks) / 10000000;//当前时间戳
            string timestamp = "timestamp=" + utck;
            string message_type = "message_type=" + pushType;
            var messageObj = new
            {
                builder_id = 0,
                content = msg,
                title = title
            };
            string message = "message=" + Newtonsoft.Json.JsonConvert.SerializeObject(messageObj);
            string signTxt = method + url + accessId + message + message_type + timestamp + secret_key;
            string sign = "sign=" + Jiami.GetMD5(signTxt);
            string sendData = accessId + "&" + timestamp + "&" + sign + "&" + message_type + "&" + message;
            string requestURL = "http://openapi.xg.qq.com/v2/push/all_device";
            string backTxt1 = Common.HttpConnectToServer(requestURL, sendData);
            //===============推送给ios端
            AppPushSettingInfo ios_info = pushinfolist[1];//安卓版配置信息实体【下标为1】
            string accessId2 = "access_id=" + ios_info.Access_id;
            string secret_key2 = ios_info.Secret_key;
            //获取推送环境，是开发环境还是生产环境
            string environment = System.Configuration.ConfigurationManager.AppSettings["pushEnvironment"];
            string environmentTxt = "environment=" + environment;
            var messageObj2 = new
            {
                aps = new
                {
                    alert = msg,
                    sound = "beep.wav"
                }
            };
            string message_type2 = "message_type=0";
            string message2 = "message=" + Newtonsoft.Json.JsonConvert.SerializeObject(messageObj2);
            string signTxt2 = method + url + accessId2 + environmentTxt + message2 + message_type2 + timestamp + secret_key2;
            string sign2 = "sign=" + Jiami.GetMD5(signTxt2);
            string sendData2 = accessId2 + "&" + environmentTxt + "&" + timestamp + "&" + sign2 + "&" + message2 + "&" + message_type2;
            string backTxt2 = Common.HttpConnectToServer(requestURL, sendData2);

            PushBackMsg pushmsg = new PushBackMsg();
            int kk = 0;//执行结果，大于1就表示成功
            //android消息
            if (backTxt1.Contains("err_msg"))
            {
                XgApiBackMsg xgapimsg = Newtonsoft.Json.JsonConvert.DeserializeObject<XgApiBackMsg>(backTxt1);
                pushmsg.msg = "android=" + xgapimsg.err_msg;
            }
            else
            {
                kk += 1;
                pushmsg.msg += "android=success";//成功
            }
            //ios消息
            if (backTxt2.Contains("err_msg"))
            {
                XgApiBackMsg xgapimsg = Newtonsoft.Json.JsonConvert.DeserializeObject<XgApiBackMsg>(backTxt2);
                pushmsg.msg += ";ios=" + xgapimsg.err_msg;
            }
            else
            {
                kk += 1;
                pushmsg.msg += ",ios=success";//成功
            }
            if (kk >= 1)
            {
                pushmsg.code = 0;
            }
            else
            {
                pushmsg.code = 1;//表示推送失败
            }
            return pushmsg;
        }

        /// <summary>
        /// 【通知】推送给指定标签的设备
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="msg">消息</param>
        /// <param name="tag">标签</param>
        /// <param name="pushType">消息类型</param>
        /// <returns></returns>
        public PushBackMsg TagsDevice(string title, string msg, string tag, string pushType, List<AppPushSettingInfo> pushinfolist)
        {
            string method = "POST";
            string url = "openapi.xg.qq.com/v2/push/tags_device";
            AppPushSettingInfo android_info = pushinfolist[0];//安卓版配置信息实体【下标为0】
            string accessId = "access_id=" + android_info.Access_id;
            string secret_key = android_info.Secret_key;
            long utck = (DateTime.UtcNow.Ticks - Convert.ToDateTime("1970-01-01").Ticks) / 10000000;//当前时间戳
            string timestamp = "timestamp=" + utck;
            string message_type = "message_type=" + pushType;//消息类型
            string tags_list = "tags_list=[\"" + tag + "\"]";//标签
            string tags_op = "tags_op=OR";
            var messageObj = new
            {
                builder_id = 0,
                content = msg,
                title = title
            };
            string message = "message=" + Newtonsoft.Json.JsonConvert.SerializeObject(messageObj);
            string signTxt = method + url + accessId + message + message_type + tags_list + tags_op + timestamp + secret_key;
            string sign = "sign=" + Jiami.GetMD5(signTxt);
            string sendData = accessId + "&" + timestamp + "&" + sign + "&" + message_type + "&" + tags_list + "&" + tags_op + "&" + message;
            string requestURL = "http://openapi.xg.qq.com/v2/push/tags_device";
            string backTxt1 = Common.HttpConnectToServer(requestURL, sendData);
            //===============推送给ios端
            AppPushSettingInfo ios_info = pushinfolist[1];//安卓版配置信息实体【下标为1】
            string accessId2 = "access_id=" + ios_info.Access_id;
            string secret_key2 = ios_info.Secret_key;
            //获取推送环境，是开发环境还是生产环境
            string environment = System.Configuration.ConfigurationManager.AppSettings["pushEnvironment"];
            string environmentTxt = "environment=" + environment;
            var messageObj2 = new
            {
                aps = new
                {
                    alert = msg,
                    sound = "beep.wav"
                }
            };
            string message_type2 = "message_type=0";
            string message2 = "message=" + Newtonsoft.Json.JsonConvert.SerializeObject(messageObj2);
            string signTxt2 = method + url + accessId2 + environmentTxt + message2 + message_type2 + tags_list + tags_op + timestamp + secret_key2;
            string sign2 = "sign=" + Jiami.GetMD5(signTxt2);
            string sendData2 = accessId2 + "&" + tags_list + "&" + tags_op + "&" + environmentTxt + "&" + timestamp + "&" + sign2 + "&" + message2 + "&" + message_type2;
            string backTxt2 = Common.HttpConnectToServer(requestURL, sendData2);

            PushBackMsg pushmsg = new PushBackMsg();
            int kk = 0;//执行结果，大于1就表示成功
            //android消息
            if (backTxt1.Contains("err_msg"))
            {
                XgApiBackMsg xgapimsg = Newtonsoft.Json.JsonConvert.DeserializeObject<XgApiBackMsg>(backTxt1);
                pushmsg.msg = "android=" + xgapimsg.err_msg;
            }
            else
            {
                kk += 1;
                pushmsg.msg += "android=success";//成功
            }
            //ios消息
            if (backTxt2.Contains("err_msg"))
            {
                XgApiBackMsg xgapimsg = Newtonsoft.Json.JsonConvert.DeserializeObject<XgApiBackMsg>(backTxt2);
                pushmsg.msg += ";ios=" + xgapimsg.err_msg;
            }
            else
            {
                kk += 1;
                pushmsg.msg += ",ios=success";//成功
            }
            if (kk >= 1)
            {
                pushmsg.code = 0;
            }
            else
            {
                pushmsg.code = 1;//表示推送失败
            }
            return pushmsg;
        }

        /// <summary>
        /// 【通知】推送给指定账号的设备
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="msg">消息</param>
        /// <param name="account">账号</param>
        /// <param name="pushType">消息类型</param>
        /// <returns></returns>
        public PushBackMsg SingleAccount(string title, string msg, string account, string pushType, List<AppPushSettingInfo> pushinfolist)
        {
            string method = "POST";
            string url = "openapi.xg.qq.com/v2/push/single_account";
            AppPushSettingInfo android_info = pushinfolist[0];//安卓版配置信息实体【下标为0】
            string accessId = "access_id=" + android_info.Access_id;
            string secret_key = android_info.Secret_key;
            long utck = (DateTime.UtcNow.Ticks - Convert.ToDateTime("1970-01-01").Ticks) / 10000000;//当前时间戳
            string timestamp = "timestamp=" + utck;
            string message_type = "message_type=" + pushType;//消息类型
            string account2 = "account=" + account;//账号             
            var messageObj = new
            {
                builder_id = 0,
                content = msg,
                title = title
            };
            string message = "message=" + Newtonsoft.Json.JsonConvert.SerializeObject(messageObj);
            string signTxt = method + url + accessId + account2 + message + message_type + timestamp + secret_key;
            string sign = "sign=" + Jiami.GetMD5(signTxt);
            string sendData = accessId + "&" + account2 + "&" + timestamp + "&" + sign + "&" + message_type + "&" + message;
            string requestURL = "http://openapi.xg.qq.com/v2/push/single_account";
            string backTxt1 = Common.HttpConnectToServer(requestURL, sendData);
            //===============推送给ios端
            AppPushSettingInfo ios_info = pushinfolist[1];//安卓版配置信息实体【下标为1】
            string accessId2 = "access_id=" + ios_info.Access_id;
            string secret_key2 = ios_info.Secret_key;
            //获取推送环境，是开发环境还是生产环境
            string environment = System.Configuration.ConfigurationManager.AppSettings["pushEnvironment"];
            string environmentTxt = "environment=" + environment;
            var messageObj2 = new
            {
                aps = new
                {
                    alert = msg,
                    sound = "beep.wav"
                }
            };
            string message2 = "message=" + Newtonsoft.Json.JsonConvert.SerializeObject(messageObj2);
            string signTxt2 = method + url + accessId2 + account2 + environmentTxt + message2 + message_type + timestamp + secret_key2;
            string sign2 = "sign=" + Jiami.GetMD5(signTxt2);
            string sendData2 = accessId2 + "&" + account2 + "&" + environmentTxt + "&" + timestamp + "&" + sign2 + "&" + message2 + "&" + message_type;
            string backTxt2 = Common.HttpConnectToServer(requestURL, sendData2);

            PushBackMsg pushmsg = new PushBackMsg();
            int kk = 0;//执行结果，大于1就表示成功
            //android消息
            if (backTxt1.Contains("err_msg"))
            {
                XgApiBackMsg xgapimsg = Newtonsoft.Json.JsonConvert.DeserializeObject<XgApiBackMsg>(backTxt1);
                pushmsg.msg = "android=" + xgapimsg.err_msg;
            }
            else
            {
                kk += 1;
                pushmsg.msg += "android=success";//成功
            }
            //ios消息
            if (backTxt2.Contains("err_msg"))
            {
                XgApiBackMsg xgapimsg = Newtonsoft.Json.JsonConvert.DeserializeObject<XgApiBackMsg>(backTxt2);
                pushmsg.msg += ";ios=" + xgapimsg.err_msg;
            }
            else
            {
                kk += 1;
                pushmsg.msg += ",ios=success";//成功
            }
            if (kk >= 1)
            {
                pushmsg.code = 0;
            }
            else
            {
                pushmsg.code = 1;//表示推送失败
            }
            return pushmsg;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}